﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using NC.Cather;
using NC.Infrastructure.Data;
using NC.Infrastructure.Domain;
using NC.Infrastructure.Domain.Identity;
using NC.Infrastructure.Domain.News;
using NC.Infrastructure.Domain.Record;

namespace NC.Infrastructure
{
    public class NCDbContext:DbContext,IUnitOfWork
    {
        public NCDbContext() : base("default")
        {
        }

        public DbSet<Target> Targets { get; set; }
        public DbSet<Person> Persons { get; set; }
        public DbSet<ApiRecord> ApiRecords { get; set; }
        public DbSet<Apply> Applies { get; set; }
        public DbSet<ContentExtendParams> ContentExtendParamses { get; set; }
        public DbSet<ContentParams> ContentParamses { get; set; }
        public DbSet<UrlList> UrlLists { get; set; }
        public DbSet<TargetPerson> TargetPersons { get; set; }

        #region Method

        public int Commit()
        {
            return this.SaveChanges();
        }

        public IDbSet<TEntity> Set<TEntity>() where TEntity : BaseEntity
        {
            return base.Set<TEntity>();
        }


        public IEnumerable<TElement> SqlQuery<TElement>(string sql, params object[] parameters)
        {
            return base.Database.SqlQuery<TElement>(sql, parameters);
        }

        //是否开启事务
        public int ExecuteSqlCommand(string sql, bool doNotEnsureTransaction = false, int? timeout = null, params object[] parameters)
        {
            int? previousTimeout = null;
            if (timeout.HasValue)
            {
                previousTimeout = ((IObjectContextAdapter)this).ObjectContext.CommandTimeout;
                ((IObjectContextAdapter)this).ObjectContext.CommandTimeout = timeout;
            }

            var transactionalBehavior = doNotEnsureTransaction
                ? TransactionalBehavior.DoNotEnsureTransaction
                : TransactionalBehavior.EnsureTransaction;
            var result = this.Database.ExecuteSqlCommand(transactionalBehavior, sql, parameters);

            if (timeout.HasValue)
            {
                ((IObjectContextAdapter)this).ObjectContext.CommandTimeout = previousTimeout;
            }
            return result;
        }

        public void Detach(object entity)
        {
            if (entity == null)
                throw new Exception("Detach对象出错！");
            ((IObjectContextAdapter)this).ObjectContext.Detach(entity);
        }

        public TEntity AttachEntityToContext<TEntity>(TEntity entity, EntityState state = EntityState.Modified) where TEntity : BaseEntity
        {
            var alreadyAttached = Set<TEntity>().Local.FirstOrDefault(x => x.Id == entity.Id);
            if (alreadyAttached == null)
            {
                Set<TEntity>().Attach(entity);
                this.Entry(entity).State = state;
                return entity;
            }
            return alreadyAttached;
        }

        #endregion


        #region Unilities


        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            //没有必要在这里进行配置扫描注入

//            //进行扫描配置，屏蔽了手动添加配置Configuration
//            Type[] types = Assembly.GetExecutingAssembly().GetTypes()
//                .Where(n => n.BaseType.IsGenericType && n.BaseType.GetGenericTypeDefinition() == typeof(TLEEntityTypeConfiguration<>)).ToArray();
//            foreach (Type type in types)
//            {
//                //动态类型
//                dynamic configurationType = Activator.CreateInstance(type);
//                modelBuilder.Configurations.Add(configurationType);
//            }
//            base.OnModelCreating(modelBuilder);
        }

        #endregion



    }
}
